{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Title: #Buddy Strings"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Difficulty: #Easy"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Category Title: #Algorithms"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Tag Slug: #hash-table #string"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Name Translated: #哈希表 #字符串"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solution Name: buddyStrings"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Title: #亲密字符串"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Translated Content:\n",
    "<p>给你两个字符串 <code>s</code> 和 <code>goal</code> ，只要我们可以通过交换 <code>s</code> 中的两个字母得到与 <code>goal</code> 相等的结果，就返回&nbsp;<code>true</code>&nbsp;；否则返回 <code>false</code> 。</p>\n",
    "\n",
    "<p>交换字母的定义是：取两个下标 <code>i</code> 和 <code>j</code> （下标从 <code>0</code> 开始）且满足 <code>i != j</code> ，接着交换 <code>s[i]</code> 和 <code>s[j]</code> 处的字符。</p>\n",
    "\n",
    "<ul>\n",
    "\t<li>例如，在 <code>\"abcd\"</code> 中交换下标 <code>0</code> 和下标 <code>2</code> 的元素可以生成 <code>\"cbad\"</code> 。</li>\n",
    "</ul>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>示例 1：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>s = \"ab\", goal = \"ba\"\n",
    "<strong>输出：</strong>true\n",
    "<strong>解释：</strong>你可以交换 s[0] = 'a' 和 s[1] = 'b' 生成 \"ba\"，此时 s 和 goal 相等。</pre>\n",
    "\n",
    "<p><strong>示例 2：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>s = \"ab\", goal = \"ab\"\n",
    "<strong>输出：</strong>false\n",
    "<strong>解释：</strong>你只能交换 s[0] = 'a' 和 s[1] = 'b' 生成 \"ba\"，此时 s 和 goal 不相等。</pre>\n",
    "\n",
    "<p><strong>示例 3：</strong></p>\n",
    "\n",
    "<pre>\n",
    "<strong>输入：</strong>s = \"aa\", goal = \"aa\"\n",
    "<strong>输出：</strong>true\n",
    "<strong>解释：</strong>你可以交换 s[0] = 'a' 和 s[1] = 'a' 生成 \"aa\"，此时 s 和 goal 相等。\n",
    "</pre>\n",
    "\n",
    "<p>&nbsp;</p>\n",
    "\n",
    "<p><strong>提示：</strong></p>\n",
    "\n",
    "<ul>\n",
    "\t<li><code>1 &lt;= s.length, goal.length &lt;= 2 * 10<sup>4</sup></code></li>\n",
    "\t<li><code>s</code> 和 <code>goal</code> 由小写英文字母组成</li>\n",
    "</ul>\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Description: [buddy-strings](https://leetcode.cn/problems/buddy-strings/description/)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Solutions: [buddy-strings](https://leetcode.cn/problems/buddy-strings/solutions/)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_cases = ['\"ab\"\\n\"ba\"', '\"ab\"\\n\"ab\"', '\"aa\"\\n\"aa\"']"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, A: str, B: str) -> bool:\n",
    "        if len(A) != len(B): return False\n",
    "        if A == B: # return False if string is of distinct characters\n",
    "            return True if len(set(A)) < len(A) else False\n",
    "        diff = []\n",
    "        for i in range(len(A)):\n",
    "            if A[i] != B[i]:\n",
    "                diff.append((A[i],B[i]))\n",
    "        return len(diff) == 2 and diff[0] == diff[1][::-1]\n",
    "                "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, A: 'str', B: 'str') -> 'bool':\n",
    "        if len(A) != len(B): \n",
    "            return False\n",
    "        if A == B:\n",
    "            return len(set(A)) < len(A)\n",
    "        \n",
    "        \n",
    "        l = len(A)\n",
    "        s1 = set()\n",
    "        s2 = set()\n",
    "        for i in range(l):\n",
    "            if A[i] != B[i]:\n",
    "                s1.add(A[i])\n",
    "                s2.add(B[i])\n",
    "                \n",
    "        \n",
    "        if len(s1) > 3 or len(s2) > 3:\n",
    "            return False\n",
    "        elif len(s1) == 0:\n",
    "            return True\n",
    "        else:\n",
    "            return len([x for x in s1 if x in s2]) == 2"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, A, B):\n",
    "        \"\"\"\n",
    "        :type A: str\n",
    "        :type B: str\n",
    "        :rtype: bool\n",
    "        \"\"\"\n",
    "        if len(A) != len(B):\n",
    "            return False\n",
    "        if not A:\n",
    "            return False\n",
    "        ids = []\n",
    "        for i in range(len(A)):\n",
    "            if A[i] != B[i]:\n",
    "                ids.append(i)\n",
    "        if len(ids) == 0:\n",
    "            return collections.Counter(list(A)).most_common(1)[0][1] > 1\n",
    "        elif len(ids) == 2:\n",
    "            i, j = ids\n",
    "            return A[i] == B[j] and A[j] == B[i]\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, A, B):\n",
    "        \"\"\"\n",
    "        :type A: str\n",
    "        :type B: str\n",
    "        :rtype: bool\n",
    "        \"\"\"\n",
    "        if not A and not B:\n",
    "            return False \n",
    "        la = len(A)\n",
    "        lb = len(B)\n",
    "        if la != lb:\n",
    "            return False\n",
    "        i = 0\n",
    "        f1 = f2 = -1\n",
    "        while i < la:\n",
    "            if A[i] == B[i]:\n",
    "                pass\n",
    "            elif f1 == -1:\n",
    "                f1 = i\n",
    "            elif f2 == -1:\n",
    "                f2 = i\n",
    "                if A[f1] != B[f2] or B[f1] != A[f2]:\n",
    "                    return False\n",
    "            else:\n",
    "                return False\n",
    "            i += 1\n",
    "        if f1 == -1 and f2 == -1:\n",
    "            return len(set(A)) != len(A)\n",
    "        if f1 != -1 and f2 == -1:\n",
    "            return False\n",
    "        return True\n",
    "            \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, A, B):\n",
    "        \"\"\"\n",
    "        :type A: str\n",
    "        :type B: str\n",
    "        :rtype: bool\n",
    "        \"\"\"\n",
    "        n=len(A)\n",
    "        if n!=len(B) or n<2:\n",
    "            return False\n",
    "        if n==2:\n",
    "            return A==B[::-1]\n",
    "        if A==B:\n",
    "            return n!=len(set(A))\n",
    "                \n",
    "        da,db = {},{}\n",
    "        count=0\n",
    "        for i in range(n):\n",
    "            da[A[i]] = da.get(A[i],0)+1\n",
    "            db[B[i]] = db.get(B[i],0)+1\n",
    "            if A[i]!=B[i]:\n",
    "                count+=1\n",
    "        return count==2 and da==db\n",
    "        \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, A, B):\n",
    "        \"\"\"\n",
    "        :type A: str\n",
    "        :type B: str\n",
    "        :rtype: bool\n",
    "        \"\"\"\n",
    "        if len(A)==0 or len(B)==0:\n",
    "            return False\n",
    "        if len(A)!=len(B):\n",
    "            return False\n",
    "        if len(A)==1:\n",
    "            return False\n",
    "        \n",
    "        list_A=list(A)\n",
    "        list_B=list(B)\n",
    "        \n",
    "        if A==B:\n",
    "            if len(list(set(list_A)))<len(list_A):\n",
    "                return True\n",
    "\n",
    "        i=0\n",
    "        j=len(list_A)-1\n",
    "        while i<len(list_A) and list_A[i]==list_B[i]:\n",
    "            i+=1\n",
    "        while j>=0 and list_A[j]==list_B[j]:\n",
    "            j-=1\n",
    "        if j<=i:\n",
    "            return False\n",
    "        temp=list_B[j]\n",
    "        list_B[j]=list_B[i]\n",
    "        list_B[i]=temp\n",
    "        if \"\".join(list_A)==\"\".join(list_B):\n",
    "            return True\n",
    "        else:\n",
    "            return False\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, A, B):\n",
    "        \"\"\"\n",
    "        :type A: str\n",
    "        :type B: str\n",
    "        :rtype: bool\n",
    "        \"\"\"\n",
    "        n1 = len(A)\n",
    "        n2 = len(B)\n",
    "        c = []\n",
    "        if n1 != n2:\n",
    "            return(False)\n",
    "        A = list(A)\n",
    "        B = list(B)\n",
    "        for i in range(n1):\n",
    "            if A[i] != B[i]:\n",
    "                c.append(i)\n",
    "        if A == B :\n",
    "            B = set(A)\n",
    "            return(len(B)<len(A))\n",
    "        if len(c) != 2 :\n",
    "            return(False)\n",
    "        if len(c) == 2:\n",
    "            if A[c[0]] == B[c[1]]:\n",
    "                return(A[c[1]] == B[c[0]])\n",
    "            else:\n",
    "                return(False)\n",
    "                \n",
    "            "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, A, B):\n",
    "        \"\"\"\n",
    "        :type A: str\n",
    "        :type B: str\n",
    "        :rtype: bool\n",
    "        \"\"\"\n",
    "        if not A or not B:\n",
    "            return False\n",
    "        if A == B:\n",
    "            if len(A) - len(set(A)) >= 1:\n",
    "                return True\n",
    "            else:\n",
    "                return False\n",
    "        \n",
    "        a, b = list(A), list(B)\n",
    "        if sorted(a) != sorted(b):\n",
    "            return False\n",
    "        \n",
    "        count = 0\n",
    "        for i in range(len(a)):\n",
    "            if a[i] != b[i]:\n",
    "                count += 1\n",
    "            if count > 2:\n",
    "                return False\n",
    "        \n",
    "        return True\n",
    "            \n",
    "            \n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, A, B):\n",
    "        \"\"\"\n",
    "        :type A: str\n",
    "        :type B: str\n",
    "        :rtype: bool\n",
    "        \"\"\"\n",
    "        if len(A)<2 or len(B)<2:return False\n",
    "        a=list(A)\n",
    "        a.sort()\n",
    "        b=list(B)\n",
    "        b.sort()\n",
    "        if a!=b:return False\n",
    "        a1=list(map(ord,A))\n",
    "        b1=list(map(ord,B))\n",
    "        c=[]\n",
    "        for i in range(len(A)):\n",
    "            c.append(a1[i]-b1[i])\n",
    "        if (len(A)-c.count(0)) > 2:\n",
    "            return False\n",
    "        elif (len(A)-c.count(0)) == 2:\n",
    "            return True\n",
    "        else:\n",
    "            if len(set(A))==len(A):\n",
    "                return False\n",
    "            else:\n",
    "                return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, A: 'str', B: 'str') -> 'bool':\n",
    "        if set(A) != set(B):\n",
    "            return False\n",
    "        if A == B and len(set(A)) != len(A):\n",
    "            return True\n",
    "        a = {}\n",
    "        b = {}\n",
    "        for i in range(len(A)):\n",
    "            if A[i] in a:\n",
    "                a[A[i]].append(i)\n",
    "            else:\n",
    "                a[A[i]] = [i]\n",
    "        for i in range(len(B)):\n",
    "            if B[i] in b:\n",
    "                b[B[i]].append(i)\n",
    "            else:\n",
    "                b[B[i]] = [i]\n",
    "        r1 = []\n",
    "        r2 = []\n",
    "        for i in a:\n",
    "            if a[i] != b[i]:\n",
    "                for k in a[i]:\n",
    "                    if k not in b[i]:\n",
    "                        r1.append(k)\n",
    "                for m in b[i]:\n",
    "                    if m not in a[i]:\n",
    "                        r2.append(m)\n",
    "        return len(r1) == 2 and r1 == r2[::-1]\n",
    "                        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, A: 'str', B: 'str') -> 'bool':\n",
    "        if set(A) != set(B):\n",
    "            return False\n",
    "        if A == B and len(set(A)) != len(A):\n",
    "            return True\n",
    "        a = {}\n",
    "        b = {}\n",
    "        for i in range(len(A)):\n",
    "            if A[i] in a:\n",
    "                a[A[i]].append(i)\n",
    "            else:\n",
    "                a[A[i]] = [i]\n",
    "        for i in range(len(B)):\n",
    "            if B[i] in b:\n",
    "                b[B[i]].append(i)\n",
    "            else:\n",
    "                b[B[i]] = [i]\n",
    "        r1 = []\n",
    "        r2 = []\n",
    "        for i in a:\n",
    "            if a[i] != b[i]:\n",
    "                for k in a[i]:\n",
    "                    if k not in b[i]:\n",
    "                        r1.append(k)\n",
    "                for m in b[i]:\n",
    "                    if m not in a[i]:\n",
    "                        r2.append(m)\n",
    "        return len(r1) == 2 and r1 == r2[::-1]\n",
    "                        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, A: str, B: str) -> bool:\n",
    "        # 长度不同直接false\n",
    "        if len(A) != len(B): return False\n",
    "        \n",
    "        # 由于必须交换一次，在相同的情况下，交换相同的字符\n",
    "        if A == B and len(set(A)) < len(A): return True\n",
    "        \n",
    "        # 使用 zip 进行匹配对比，挑出不同的字符对\n",
    "        dif = [(a, b) for a, b in zip(A, B) if a != b]\n",
    "        \n",
    "        # 对数只能为2，并且对称，如 (a,b)与(b,a)\n",
    "        return len(dif) == 2 and dif[0] == dif[1][::-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, A: str, B: str) -> bool:\n",
    "        mark = []\n",
    "        count = 0\n",
    "        if len(A) == len(B):\n",
    "            lenth = len(A)\n",
    "        else: return False\n",
    "        for i in range(lenth):\n",
    "            if count <=2:\n",
    "                if A[i] != B[i]:\n",
    "                    count +=1\n",
    "                    mark.append(i)\n",
    "            else: return False\n",
    "        if count==0:\n",
    "            seen = set()\n",
    "            for a in A:\n",
    "                if a in seen:\n",
    "                    return True\n",
    "                seen.add(a)\n",
    "            return False \n",
    "        if count !=2: return False\n",
    "        if A[mark[0]]==B[mark[1]] and A[mark[1]]==B[mark[0]]:\n",
    "            return True\n",
    "        else: return False\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, A: str, B: str) -> bool:\n",
    "        if len(A) != len(B): return False\n",
    "        if A == B:\n",
    "            seen = set()\n",
    "            for a in A:\n",
    "                if a in seen:\n",
    "                    return True\n",
    "                seen.add(a)\n",
    "            return False\n",
    "        else:\n",
    "            pairs = []\n",
    "            for a, b in zip(A, B):\n",
    "                if a != b:\n",
    "                    pairs.append((a, b))\n",
    "                if len(pairs) >= 3: return False\n",
    "            return len(pairs) == 2 and pairs[0] == pairs[1][::-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, A: str, B: str) -> bool:\n",
    "        n_A, n_B = len(A), len(B)\n",
    "        if n_A != n_B: \n",
    "            return False\n",
    "        if A == B:\n",
    "            for c in A:\n",
    "                if A.count(c) > 1: \n",
    "                    return True\n",
    "        diff = []\n",
    "        for i in range(n_A):\n",
    "            if A[i] != B[i]: \n",
    "                diff.append((A[i], B[i]))\n",
    "        if len(diff) != 2 or (diff[0][0] != diff[1][1] or diff[0][1] != diff[1][0]): \n",
    "            return False\n",
    "        return True"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, A: str, B: str) -> bool:\n",
    "        if len(A) != len(B):\n",
    "            return False\n",
    "        if A == B:\n",
    "            c = set()\n",
    "            for i in A:\n",
    "                if i in c:\n",
    "                    return True\n",
    "                c.add(i)\n",
    "            return False\n",
    "        else:\n",
    "            d = []\n",
    "            for i in range(len(A)):\n",
    "                if A[i] != B[i]:\n",
    "                    d.append((A[i], B[i]))\n",
    "            return len(d) == 2 and  d[0] == d[1][::-1]\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution(object):\n",
    "    def buddyStrings(self, A, B):\n",
    "        if not A or not B or len(A) != len(B): \n",
    "            return False\n",
    "        if A == B:\n",
    "            return max(collections.Counter(A).values()) > 1\n",
    "        else:\n",
    "            pairs = []\n",
    "            for a, b in zip(A, B):\n",
    "                if a != b:\n",
    "                    pairs.append((a, b))\n",
    "                if len(pairs) >= 3: \n",
    "                    return False\n",
    "            return len(pairs) == 2 and pairs[0] == pairs[1][::-1]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, A: str, B: str) -> bool:\n",
    "        index=[]\n",
    "        if len(A)==len(B):\n",
    "            for i in range(len(A)):\n",
    "                if A[i] != B[i]:\n",
    "                    index.append(i)\n",
    "            if len(index) == 2 and A[index[0]]==B[index[1]] and A[index[1]] == B[index[0]]:\n",
    "                return True\n",
    "            if len(index) == 0 and len(A)-len(set(A)) >0:\n",
    "                return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "# 亲密字符串\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, A: str, B: str) -> bool:\n",
    "    \tif len(A) != len(B): return False\n",
    "    \tif not A: return False\n",
    "\n",
    "    \tnum_diff = 0\n",
    "    \tdiff_char = None\n",
    "\n",
    "    \tfrom collections import Counter\n",
    "\n",
    "    \tfor a,b in zip(A, B):\n",
    "    \t\tif a != b:\n",
    "    \t\t\tnum_diff += 1\n",
    "    \t\t\tif num_diff > 2:\n",
    "    \t\t\t\treturn False\n",
    "    \t\t\telif num_diff == 2:\n",
    "    \t\t\t\tif diff_char == (b, a):\n",
    "    \t\t\t\t\tpass\n",
    "    \t\t\t\t\t# 验证通过但是不返回，继续扫描\n",
    "    \t\t\t\telse:\n",
    "    \t\t\t\t\treturn False\n",
    "    \t\t\telif num_diff == 1:\n",
    "    \t\t\t\tdiff_char = (a, b)\n",
    "\n",
    "    \tif num_diff == 2: return True\n",
    "    \tif num_diff == 0: return Counter(A).most_common(1)[0][1] >= 2\n",
    "    \treturn False\n",
    "\n",
    "print(Solution().buddyStrings(\"aa\", \"aa\"))\n",
    "print(Solution().buddyStrings(\"abc\", \"acd\"))\n",
    "print(Solution().buddyStrings(\"abc\", \"acb\"))\n",
    "print(Solution().buddyStrings(\"abc\", \"\"))\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, A: str, B: str) -> bool:\n",
    "        if len(A) != len(B):\n",
    "            return False \n",
    "        \n",
    "        # if A == B:\n",
    "        if A == B and len(set(A)) < len(A):\n",
    "            return True \n",
    "\n",
    "        # swap\n",
    "        differences = []\n",
    "        for x in range(len(A)):\n",
    "            if A[x]!= B[x]:\n",
    "                differences.append([A[x], B[x]])\n",
    "        \n",
    "        # (x, y) (y, x)\n",
    "        if len(differences) == 2 and differences[0] == differences[-1][::-1]:\n",
    "            return True \n",
    "\n",
    "\n",
    "        return False\n",
    "        "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, A: str, B: str) -> bool:\n",
    "        if len(A)!=len(B):\n",
    "            return False\n",
    "        lista=[]\n",
    "        listb=[]\n",
    "        \n",
    "        index=[]\n",
    "        count=0\n",
    "        for i in range(len(A)):\n",
    "            lista.append(A[i])\n",
    "            listb.append(B[i])\n",
    "            if A[i] != B[i]:\n",
    "                count=count+1\n",
    "                index.append(i)\n",
    "                \n",
    "        if count==1 or count>2:\n",
    "            return False\n",
    "        if len(index)<2 :\n",
    "            if len(A)>len(set(A)):\n",
    "                return True\n",
    "            else:\n",
    "                return False\n",
    "        return (A[index[0]]==B[index[1]] and A[index[1]]==B[index[0]])    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, A: str, B: str) -> bool:\n",
    "        if not A or len(A)!=len(B) or len(A)<2:\n",
    "            return False\n",
    "        A = list(A)\n",
    "        B = list(B)\n",
    "        c=A+B[::-1]\n",
    "        temp=[]\n",
    "        if A!=B:\n",
    "            left=0\n",
    "            right=len(c)-1\n",
    "            while(left<=right):\n",
    "                if c[left]!=c[right]:\n",
    "                    temp.append(left)\n",
    "                left+=1\n",
    "                right-=1\n",
    "            if c[temp[0]] in B and c[temp[1]] in B:\n",
    "                A[temp[0]],A[temp[1]]=A[temp[1]],A[temp[0]]\n",
    "            return A==B\n",
    "        else:\n",
    "            return set(A)==set(B) and len(A)>len(set(A))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, s: str, goal: str) -> bool:\n",
    "        a, b = Counter(s), Counter(goal)\n",
    "        flag = False\n",
    "        for i in a:\n",
    "            if a[i] != b[i]:\n",
    "                return False\n",
    "            if a[i] > 1:\n",
    "                flag = True\n",
    "\n",
    "        cnt, n = 0, len(s)\n",
    "        for j in range(n):\n",
    "            if s[j] != goal[j]:\n",
    "                cnt += 1\n",
    "        return cnt == 2 or cnt == 0 and flag\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, s: str, goal: str) -> bool:\n",
    "        #两个字符串长度不一致一定不是亲密字符串\n",
    "        #亲密字符串的条件：1、两个字符串不同字符数量为2（刚好可以交换）\n",
    "        #2、两个字符串不同字符数量为0，但是存在相同字符超过2的情况（相同字符交换）\n",
    "        if len(s) != len(goal): return False\n",
    "        cn1 = [0]*26\n",
    "        cn2 = [0]*26\n",
    "        sum = 0\n",
    "        for i in range(len(s)):\n",
    "            cn1[ord(s[i]) - ord(\"a\")] += 1\n",
    "            cn2[ord(goal[i]) - ord(\"a\")] += 1\n",
    "            if ord(s[i]) - ord(\"a\") != ord(goal[i]) - ord(\"a\"): sum += 1\n",
    "        ok = False\n",
    "        for i in range(26):\n",
    "            if cn1[i] != cn2[i]: return False\n",
    "            if cn1[i] > 1: ok = True\n",
    "        return sum == 2 or (sum == 0 and ok)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, s: str, goal: str) -> bool:\n",
    "        if len(s) != len(goal):\n",
    "            return False\n",
    "        if s == goal:\n",
    "            if len(set(s)) == len(goal):\n",
    "                return False\n",
    "            else:\n",
    "                return True\n",
    "        diff = [[a, b] for a,b in zip(s, goal) if a != b]\n",
    "        return len(diff) == 2 and diff[0][0] == diff[1][1] and diff[0][1] == diff[1][0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\r\n",
    "    def buddyStrings(self, s: str, goal: str) -> bool:\r\n",
    "        len_s = len(s)\r\n",
    "        if len_s != len(goal):\r\n",
    "            return False\r\n",
    "        hashmap = {}\r\n",
    "        for i, d in enumerate(s):\r\n",
    "            if d == goal[i]:\r\n",
    "                continue\r\n",
    "            hashmap[i] = [d, goal[i]]\r\n",
    "        if len(hashmap) == 0:\r\n",
    "            return len_s - len(set(s)) >= 1\r\n",
    "        if len(hashmap) != 2:\r\n",
    "            return False\r\n",
    "        values = list(hashmap.values())\r\n",
    "        return values[0][0] == values[1][1] and values[0][1] == values[1][0]\r\n",
    "\r\n",
    "\r\n",
    "if __name__ == \"__main__\":\r\n",
    "    sol = Solution()\r\n",
    "    print(sol.buddyStrings(\"abc\", \"abc\"))\r\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, s: str, goal: str) -> bool:\n",
    "        if len(set(s)) != len(s) and s==goal:\n",
    "            return True\n",
    "        s=list(s)\n",
    "        goal=list(goal)\n",
    "        l=[]\n",
    "        for i in range(len(s)):\n",
    "            if s[i] != goal[i]:\n",
    "                l.append(i)\n",
    "        if len(l) !=2:\n",
    "            return False\n",
    "        else:\n",
    "            s[l[0]],s[l[1]]=s[l[1]],s[l[0]]\n",
    "            return str(s)==str(goal)\n",
    "                \n",
    "                    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "#202042120110叶方清\n",
    "class Solution:\n",
    "    def buddyStrings(self, s: str, goal: str) -> bool:\n",
    "        #若s与goal相等且存在重复元素，则交换之后也相等\n",
    "        if len(set(s)) != len(s) and s==goal:\n",
    "            return True\n",
    "        s=list(s)\n",
    "        goal=list(goal)\n",
    "        l=[]\n",
    "        for i in range(len(s)):\n",
    "            #若两个字符串中对应下标的元素不相等，则将下标追加到空列表l中\n",
    "            if s[i] != goal[i]:\n",
    "                l.append(i)\n",
    "        #若新列表长度不等于2，则不能交换，直接返回False;否则进行序列解包进行交换\n",
    "        if len(l) !=2:\n",
    "            return False\n",
    "        else:\n",
    "            s[l[0]],s[l[1]]=s[l[1]],s[l[0]] #序列解包\n",
    "            return str(s)==str(goal)\n",
    "                \n",
    "                    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, s: str, goal: str) -> bool:\n",
    "        if len(s) != len(goal):\n",
    "            return False\n",
    "\n",
    "        rs, gs, cnt = dict(), dict(), 0\n",
    "        for i in range(len(s)):\n",
    "            if s[i] not in goal or goal[i] not in s:\n",
    "                return False\n",
    "\n",
    "            if s[i] in rs:\n",
    "                rs[s[i]] += 1\n",
    "            else:\n",
    "                rs[s[i]] = 1\n",
    "\n",
    "            if goal[i] in gs:\n",
    "                gs[goal[i]] += 1\n",
    "            else:\n",
    "                gs[goal[i]] = 1\n",
    "\n",
    "            if s[i] != goal[i]:\n",
    "                cnt += 1\n",
    "                if cnt>2:\n",
    "                    return False\n",
    "        \n",
    "        if cnt not in [0, 2]:\n",
    "            return False\n",
    "\n",
    "        for x in rs:\n",
    "            if cnt == 0 and rs[x]>1:\n",
    "                return True\n",
    "\n",
    "            if rs[x]!=gs[x]:\n",
    "                return False \n",
    "        \n",
    "        if cnt==2:\n",
    "            return True\n",
    "\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, s: str, goal: str) -> bool:\n",
    "        if len(s)!=len(goal):\n",
    "            return False\n",
    "        ds=''\n",
    "        dg=''\n",
    "        for i in range(len(s)):\n",
    "            if s[i]!=goal[i]:\n",
    "                if ds=='#':\n",
    "                    return False\n",
    "                if ds=='':\n",
    "                    ds=s[i]\n",
    "                    dg=goal[i]\n",
    "                else:\n",
    "                    if s[i]!=dg or goal[i]!=ds:\n",
    "                        return False\n",
    "                    ds='#'\n",
    "                    dg='#'\n",
    "        if ds=='#':\n",
    "            return True\n",
    "        if ds=='':\n",
    "            counts=Counter(s)\n",
    "            for c in counts:\n",
    "                if counts[c]>=2:\n",
    "                    return True\n",
    "        return False"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from typing import List\n",
    "import collections\n",
    "\n",
    "class Solution:\n",
    "    def buddyStrings(self, s: str, goal: str) -> bool:\n",
    "        if len(s) != len(goal):\n",
    "            return False\n",
    "        if s == goal:\n",
    "            if len(set(s)) < len(goal): \n",
    "                return True\n",
    "            else:\n",
    "                return False\n",
    "        diff = [(a, b) for a, b in zip(s, goal) if a != b]\n",
    "        return len(diff) == 2 and diff[0][0] == diff[1][1] and diff[0][1] == diff[1][0]\n",
    "\n"
   ]
  }
 ],
 "metadata": {},
 "nbformat": 4,
 "nbformat_minor": 2
}
